package WbComment.file;

import WbComment.pojo.Comment;
import WbComment.util.Html;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelWriter;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 爬虫部分
 */
public class Spider {
    final private String BASE_URL = "https://m.weibo.cn/comments/hotflow?id=%s&mid=%s&max_id_type=0";
    final private String CHILD_URL = "https://m.weibo.cn/comments/hotFlowChild?cid=%s&max_id_type=0";
    // 子部分
    private iFrame frame;
    private String strCookie;
    private String strAddress;
    Spider(Window window, String strCookie, String strAddress) {
        this.frame = window;
        this.strCookie = strCookie;
        this.strAddress = strAddress;
    }

    // 爬虫处理
    public void process() {
        frame.showMsg("【处理开始...】");

        try {
            // 查询数据并输出
            List<Comment> list = getBasePageComment();
            if(null != list && !list.isEmpty()){
                handleData(list);
                outExecl(list);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        frame.showMsg("【处理结束...】");
    }

    // 取得文章基本评论
    private List<Comment> getBasePageComment() throws InterruptedException {
        List<Comment> listRet = new ArrayList<>();
        Long maxId = 0L;
        while (1==1){
            // 基本请求处理
            JSONObject jsonBase = htmlRequest(BASE_URL, strAddress, maxId);
            if(null == jsonBase){
                break;
            }
            // 结果处理
            JSONObject jsonData = jsonBase.getJSONObject("data");
            maxId = jsonData.getLong("max_id"); // 最大id
            // 结果的评论信息
            JSONArray arrayComment = jsonData.getJSONArray("data");
            if(!arrayComment.isEmpty()){
                List<Comment> listComment = arrayComment.toList(Comment.class);
//                getSubComment(listComment);
                listRet.addAll(listComment);
            }
            // 判断是否到最后
            if(arrayComment.isEmpty() || maxId == 0L){
                break;
            }
        }
        return listRet;
    }

    // 子评论
    private void getSubComment(List<Comment> listComment) throws InterruptedException {
        Long maxId = 0L;
        for (Comment comment : listComment){
            if (comment.getTotal_number() > 0){
                // 子请求
                JSONObject jsonBase = htmlRequest(CHILD_URL, comment.getId(), maxId);
                if(null == jsonBase){
                    continue;
                }
                // 结果处理
                maxId = jsonBase.getLong("max_id"); // 最大id
                // 结果的评论信息
                JSONArray arrayComment = jsonBase.getJSONArray("data");
                if(!arrayComment.isEmpty()){
                    List<Comment> listSubComment = arrayComment.toList(Comment.class);
                    comment.setList(listSubComment);
                }
            }
        }
    }


    /**
     * 网络请求
     */
    private JSONObject htmlRequest(String inUrl, String inAddress, Long inMaxId) throws InterruptedException {
        String url = String.format(inUrl, inAddress, inAddress);
        if(null != inMaxId && 0L != inMaxId){
            url = url + "&max_id=" + inMaxId;
        }
        frame.showMsg("请求链接：" + url);
        for (int i = 1; i <= 3; i++) {
            // 请求
            String retBase = HttpRequest.post(url)
                    .header(Header.COOKIE, strCookie) // cookie处理
                    .timeout(20000)//超时，毫秒
                    .execute().body();
            if (StrUtil.isBlank(retBase) || !JSONUtil.isJsonObj(retBase)){
                frame.showMsg("【异常】没有返回结果，请求失败：" + i);
                Thread.sleep(300);
                continue;
            }
            JSONObject jsonBase = JSONUtil.parseObj(retBase);
            if (jsonBase.getInt("ok") != 1){
                frame.showMsg("【异常】结果异常，请求失败：" + i);
                Thread.sleep(300);
                continue;
            }
            return jsonBase;
        }
        return null;
    }

    /**
     * 数据处理
     */
    private void handleData(List<Comment> list){
        for (Comment comment: list){
            // 去除标签
            comment.setText(Html.delHTMLTag(comment.getText()));
        }
    }

    // 输出文件
    private void outExecl(List<Comment> list){
        frame.showMsg("【文件输出开始...】");
        // 创建一个webbook，对应一个Excel文件
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
        // 通过工具类创建writer
        ExcelWriter writer = new ExcelWriter(xssfWorkbook,"data");
        writer.write(list);
        writer.getSheet().setColumnWidth(0,15*256);
        writer.getSheet().setColumnWidth(1,20*256);
        writer.getSheet().setColumnWidth(2,20*256);
        writer.getSheet().setColumnWidth(3,10*256);
        writer.getSheet().setColumnWidth(4,10*256);
        writer.getSheet().setColumnWidth(5,40*256);
        writer.getSheet().setColumnWidth(6,5*256);
        // 文件输出
        try {
            FileOutputStream outputStream = new FileOutputStream(new File(strAddress + ".xlsx"));
            xssfWorkbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        frame.showMsg("【文件输出结束...】");
    }
}